import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.ArrayList;

public class MyPaint extends JFrame {  //新建一个窗口类，继承JAVA的基本窗口类
    private DrawPanel drawPanel;//定义一个绘图面板，成员变量
    private JPanel comPanel;  //用来存放按钮的面板
    private JButton saveButton;  //定义一个保存按钮
    private JButton openButton;  //定义一个打开的按钮
    private JButton lineButton;//定义一个按钮，用来选择画直线
    private JButton circleButton;//定义一个按钮，用来选择画圆
    private JButton selectButton;  //定义一个按钮，使当前的状态处于选择状态
    private JButton colorButton;  //定义一个按钮，用来选择图形的颜色
    private JButton widthButton;  //定义一个按钮，用来选择图形的宽度
    private JButton deleteButton; //定义一个按钮，用来删除直线。
    private JButton insertImageButton;//定义一个插入图象按钮

    private Line line=null;//直线的对象
    private Circle circle=null;//圆的对象
    private All all=new All();//定义所有图形对象
    private boolean isStarted=false; //图形是否已经开始绘制，也就是说是否已经确定第一个点
    private Color currentColor=Color.BLACK;  //定义一个当前颜色，默认为黑色
    private int currentWidth=1; // 定义一个当前的宽度，默认为1
    private int drawType=1; //定义当前的绘制类型，1为直线，2为圆
    private Line currentSelectLine=null; //当前选择的直线
    private Line currentSelectLineTemp=null;  //鼠标经过的直线
    private Circle currentSelectCircle = null;
    private Circle currentSelectCircleTemp = null;
    private Color oldColor = null;

    public MyPaint() throws HeadlessException {
        this.setSize(800,600);//设置窗口的大小
        this.setLocationRelativeTo(null); //设置窗口的相对位置
        this.setTitle("Auto_CAD");//设置标题
        drawPanel=new DrawPanel();//初始化绘图面板

        saveButton=new JButton("保存");
        saveButton.addActionListener(new ActionListener() { //给保存按钮添加功能。
            @Override
            public void actionPerformed(ActionEvent e) {
                JFileChooser jf=new JFileChooser();
                FileNameExtensionFilter filter=new FileNameExtensionFilter("*.cad","cad");
                jf.setFileFilter(filter);
                jf.showSaveDialog(null);//显示保存对话框
                File file=jf.getSelectedFile(); //获取所选择的文件
                String filePath=file.getPath();//获取文件的路径
                if (!filePath.endsWith(".cad")){//如果文件路径不是以.cad作为结尾，则新建一个文件
                    file=new File(filePath+".cad");
                }
                try{//尝试着保存图形
                    FileOutputStream fos=new FileOutputStream(file.getAbsolutePath());//定义一个文件输出流
                    ObjectOutputStream oos=new ObjectOutputStream(fos); //对象输出流
                    oos.writeObject(all);//将图形对象写入磁盘
                    oos.close();//关闭对象输出流
                    fos.close();//关闭文件输出流
                }catch (Exception e1){
                    e1.printStackTrace();
                }
                System.out.println(filePath);

            }
        });
        openButton=new JButton("打开");//初始化打开按钮
        openButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JFileChooser jfc=new JFileChooser();//新建一个文件选择器
                FileNameExtensionFilter filter=new FileNameExtensionFilter("*.cad","cad");
                jfc.setFileFilter(filter);//
                jfc.showOpenDialog(null);//显示打开文件对话框
                File file=jfc.getSelectedFile();//获取所选择的文件
                try{//尝试着打开图形文件
                    FileInputStream fis=new FileInputStream(file.getAbsolutePath());//文件输入流
                    ObjectInputStream ois=new ObjectInputStream(fis);//对象输入流
                    all= (All) ois.readObject();//从对象输入流中读取对象
                    ois.close();//关闭对象输入流
                    fis.close();//关闭文件输入流
                    drawPanel.repaint();//刷新绘图面板
                }catch (Exception e1){
                    e1.printStackTrace();
                }
            }
        });

        lineButton=new JButton("直线");
        lineButton.setEnabled(false);
        lineButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                drawType = 1;
                deleteButton.setEnabled(false);
                lineButton.setEnabled(false);
                circleButton.setEnabled(true);
                selectButton.setEnabled(true);
                Cursor cursor=new Cursor(Cursor.CROSSHAIR_CURSOR);
                drawPanel.setCursor(cursor);
                currentSelectLine = null;
                isStarted = false;
                drawPanel.repaint();
                currentColor = oldColor;//将原来的颜色取出来
                colorButton.setBackground(currentColor);
            }
        });
        circleButton=new JButton("画圆");
        circleButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                lineButton.setEnabled(true);
                drawType=2;
                circleButton.setEnabled(false);
                selectButton.setEnabled(true);
                deleteButton.setEnabled(false);
                Cursor cursor=new Cursor(Cursor.CROSSHAIR_CURSOR);
                drawPanel.setCursor(cursor);
            }
        });
        selectButton=new JButton("选择");
        selectButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                drawType=100;
                lineButton.setEnabled(true);
                circleButton.setEnabled(true);
                selectButton.setEnabled(false);
                deleteButton.setEnabled(true);
                isStarted = false;
                Cursor cursor=new Cursor(Cursor.DEFAULT_CURSOR);//新建鼠标自的形状
                drawPanel.setCursor(cursor);//设置当前鼠标的形状为箭头
            }
        });

        deleteButton=new JButton("删除");
        deleteButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(currentSelectLine == null && currentSelectCircle == null){//如果没有选中直线，提示用户先选择直线，再进行删除
                    JOptionPane.showMessageDialog(null,"请先选择目标，再进行删除");
                    return;
                }
                all.getLineList().remove(currentSelectLine);
                all.getCircleList().remove(currentSelectCircle);
                drawPanel.repaint();//刷新绘图面板
                currentSelectLine = null;
                currentSelectCircle = null;
            }
        });
        colorButton=new JButton("颜色");  //初始化颜色选择按钮
        colorButton.setBackground(currentColor);//设置背景的颜色
        colorButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                currentColor=JColorChooser.showDialog(null,"请选择图形的颜色",Color.RED);  //显示颜色选择对话框
                colorButton.setBackground(currentColor);//设置背景的颜色

                if(currentSelectLine != null){//如果有选中的直线
                    currentSelectLine.color = currentColor;//将直线颜色设置为当前选中颜色
                    drawPanel.repaint();
                }
            }
        });

        widthButton=new JButton("宽度:"+currentWidth);
        widthButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JDialog jd=new JDialog(); //定义一个对话框
                jd.setLocationRelativeTo(null);
                jd.setSize(200,100);
                jd.setTitle("图形的宽度");
                GridLayout gridLayout=new GridLayout(2,2);//定义网格布局
                jd.getContentPane().setLayout(gridLayout); //将对话框的布局设置为新建的网格布局
                JLabel jLabel=new JLabel("线条宽度");//新建一个标签
                jd.add(jLabel);  //将标签添加到对话框中
                JTextField widthTF=new JTextField(); //新建一个文本框，用来输入线条的宽度
                jd.add(widthTF);//将宽度文本框添加到对话框中
                JButton okButton=new JButton("确定");  //定义一个确定按钮并初始化
                okButton.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        String widthString=widthTF.getText();
                        try {
                            currentWidth = Integer.parseInt(widthString);//将字符串转为整形
                            widthButton.setText("宽度:"+currentWidth);
                            jd.setVisible(false);//将对话框设为不可见
                        }catch (Exception e1){
                            JOptionPane.showMessageDialog(null,"请输入正确的数字");
                        }

                        System.out.println("宽度为："+currentWidth);
                    }
                });
                jd.add(okButton);
                JButton cancelButton=new JButton("取消");
                cancelButton.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        jd.hide();
                    }
                });
                jd.add(cancelButton);


                jd.setVisible(true);  //显示对话框
            }
        });
        insertImageButton = new JButton("插入图像");
        insertImageButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ImageFrame imageFrame = new ImageFrame();//定义并且初始化窗口

            }
        });
        comPanel=new JPanel();//初始化按钮的面板
        comPanel.add(saveButton);//将保存按钮添加到命令面板中
        comPanel.add(openButton);//将打开按钮添加到命令面板中
        comPanel.add(lineButton);//将直线按钮添加到命令面板中
        comPanel.add(circleButton);//将圆的按钮添加到命令面板中
        comPanel.add(selectButton); //将选择按钮添加到命令面板中
        comPanel.add(colorButton); //将颜色按钮添加到命令面板中
        comPanel.add(widthButton); //将宽度按钮添加到命令面板中
        comPanel.add(deleteButton);//将删除按钮添加到命令面板
        comPanel.add(insertImageButton);//将插入按钮添加到命令面板中
        this.add(comPanel,BorderLayout.NORTH);
        this.add(drawPanel,BorderLayout.CENTER);//将绘图面板放置窗口的中心

    }

    class DrawPanel extends JPanel{  //定义绘图面板，用于绘制图形
        public DrawPanel() { //构造函数，用于初始化，比如初始化绘图面板的背景
            this.setBackground(Color.white);  //设置绘图面板的背景颜色
            MouseA mouseA=new MouseA(); //定义鼠标适配器的对象，并初始化
            this.addMouseListener(mouseA);  //将鼠标适配器设置为绘图面板的鼠标侦听器
            MouseB mouseB=new MouseB();  //
            this.addMouseMotionListener(mouseB);
            Cursor cursor=new Cursor(Cursor.CROSSHAIR_CURSOR);  //定义一个十字形鼠标
            this.setCursor(cursor);//设为当前光标形状
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2= (Graphics2D) g;//将图形强制进行类型转换，转换为二维的  ALT+回车
            g2.setColor(Color.RED);//设置画笔的颜色

            for(int i=0;i<all.getLineList().size();i++){ //遍历每一根直线
                Line l=all.getLineList().get(i);//获取每一根直线
                g2.setColor(l.color);
                BasicStroke bs=new BasicStroke(l.width,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);//直线的宽度
                g2.setStroke(bs); //设置画笔的宽度
                g2.drawLine(l.x1, l.y1, l.x2, l.y2);
            }

            for(int i=0;i<all.getCircleList().size();i++){ //遍历每一个圆
                Circle c=all.getCircleList().get(i);//获取每一根直线
                g2.setColor(c.color);
                BasicStroke bs=new BasicStroke(c.width,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);//直线的宽度
                g2.setStroke(bs); //设置画笔的宽度
                int r= (int) (Math.sqrt((c.x1-c.x2)*(c.x1-c.x2)+(c.y1-c.y2)*(c.y1-c.y2))+0.5);
                g2.drawOval(c.x1-r,c.y1-r,2*r,2*r);
            }

            if(isStarted){//如果第一个点已经确定，才可以绘制橡皮筋
                if(drawType==1) {
                    g2.setColor(currentColor);
                    BasicStroke bs = new BasicStroke(currentWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);//直线的宽度
                    g2.setStroke(bs); //设置画笔的宽度
                    g2.drawLine(line.x1, line.y1, line.x2, line.y2); //绘制橡皮筋
                }else if(drawType==2){
                    g2.setColor(currentColor);
                    BasicStroke bs = new BasicStroke(currentWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);//直线的宽度
                    g2.setStroke(bs); //设置画笔的宽度
                    int r= (int) (Math.sqrt((circle.x1-circle.x2)*(circle.x1-circle.x2)+(circle.y1-circle.y2)*(circle.y1-circle.y2))+0.5);
                    g2.drawOval(circle.x1-r,circle.y1-r,2*r,2*r);
                }
            }

            if (currentSelectLineTemp!=null){//如果有捕捉到直线
                g2.setColor(Color.BLUE);//设置当前画笔的颜色为蓝色
                g2.drawRect(currentSelectLineTemp.x1-5,currentSelectLineTemp.y1-5,10,10);
                g2.drawRect(currentSelectLineTemp.x2-5,currentSelectLineTemp.y2-5,10,10);
            }
            if (currentSelectLine!=null){//如果有捕捉到直线
                g2.setColor(Color.BLUE);//设置当前画笔的颜色为蓝色
                g2.drawRect(currentSelectLine.x1-5,currentSelectLine.y1-5,10,10);
                g2.drawRect(currentSelectLine.x2-5,currentSelectLine.y2-5,10,10);
            }
            if (currentSelectCircleTemp!=null){//如果有捕捉到直线
                g2.setColor(Color.BLUE);//设置当前画笔的颜色为蓝色
                int r = getDist(currentSelectCircleTemp.x1,currentSelectCircleTemp.y1,currentSelectCircleTemp.x2,currentSelectCircleTemp.y2);
                g2.drawRect(currentSelectCircleTemp.x1-5,currentSelectCircleTemp.y1-5,10,10);
                g2.drawRect(currentSelectCircleTemp.x1-r-5,currentSelectCircleTemp.y1-5,10,10);
                g2.drawRect(currentSelectCircleTemp.x1+r-5,currentSelectCircleTemp.y1-5,10,10);
                g2.drawRect(currentSelectCircleTemp.x1-5,currentSelectCircleTemp.y1+r-5,10,10);
                g2.drawRect(currentSelectCircleTemp.x1-5,currentSelectCircleTemp.y1-r-5,10,10);
            }
            if (currentSelectCircle!=null){//如果有捕捉到直线
                g2.setColor(Color.BLUE);//设置当前画笔的颜色为蓝色
                int r = getDist(currentSelectCircle.x1,currentSelectCircle.y1,currentSelectCircle.x2,currentSelectCircle.y2);
                g2.drawRect(currentSelectCircle.x1-5,currentSelectCircle.y1-5,10,10);
                g2.drawRect(currentSelectCircle.x1-r-5,currentSelectCircle.y1-5,10,10);
                g2.drawRect(currentSelectCircle.x1+r-5,currentSelectCircle.y1-5,10,10);
                g2.drawRect(currentSelectCircle.x1-5,currentSelectCircle.y1+r-5,10,10);
                g2.drawRect(currentSelectCircle.x1-5,currentSelectCircle.y1-r-5,10,10);
            }

        }
    }

    class MouseA extends MouseAdapter{//定义一个鼠标的基本适配器，这里主要包含鼠标按下的操作
        @Override
        public void mousePressed(MouseEvent e) {
            super.mousePressed(e);
            if (!isStarted){
                if (drawType==1) {
                    line = new Line();//新建一根直线
                    line.x1 = e.getX();
                    line.y1 = e.getY();
                }else if(drawType==2){
                    circle=new Circle();//新建一个圆
                    circle.x1=e.getX();
                    circle.y1=e.getY();
                }
                isStarted=true;
            }else{
                if (drawType==1) {
                    line.x2 = e.getX();
                    line.y2 = e.getY();
                    line.color = currentColor; //将当前的颜色赋给直线
                    line.width = currentWidth; //将当前的宽度赋给直线
                    all.getLineList().add(line); //如果直线的两个点都已经确定，则将直线添加到链表中
                }else if(drawType==2){
                    circle.x2=e.getX();
                    circle.y2=e.getY();
                    circle.color=currentColor;
                    circle.width=currentWidth;
                    all.getCircleList().add(circle);
                }
                isStarted=false;
                drawPanel.repaint();
            }
            if (drawType==100){
                if(currentSelectLineTemp!=null) {//如果有捕捉到直线
                    currentSelectCircle = null;
                    currentSelectLine = currentSelectLineTemp; //确认选中直线
                    currentSelectLineTemp = null;//直线确认选中后，临时的为空
                    oldColor = currentColor;//保存原来的颜色。
                    currentColor = currentSelectLine.color;
                    colorButton.setBackground(currentColor);
                    drawPanel.repaint(); //刷新绘图面板
                }
                if(currentSelectCircleTemp!=null){
                    currentSelectLine = null;
                    currentSelectCircle = currentSelectCircleTemp; //确认选中直线
                    currentSelectCircleTemp = null;//直线确认选中后，临时的为空
                    oldColor = currentColor;//保存原来的颜色。
                    currentColor = currentSelectCircle.color;
                    colorButton.setBackground(currentColor);
                    drawPanel.repaint(); //刷新绘图面板
                }

            }


        }
    }
    class MouseB extends MouseMotionAdapter{
        @Override
        public void mouseMoved(MouseEvent e) {
            super.mouseMoved(e);
            if (isStarted) {  //图形的第一个点已经确定
                if (drawType==1) {
                    line.x2 = e.getX();
                    line.y2 = e.getY();
                }else if (drawType==2){
                    circle.x2=e.getX();
                    circle.y2=e.getY();
                }
                drawPanel.repaint();//刷新绘图面板
            }
            if (drawType==100){//如果当前绘图状态属于选择状态
                for (int i=0;i<all.getLineList().size();i++){//遍历每一根直线
                    Line lineTemp=all.getLineList().get(i);  //获取第i根直线
                    int x1_x2=getDist(lineTemp.x1,lineTemp.y1,lineTemp.x2,lineTemp.y2); //直线的长度
                    int e_x1=getDist(e.getX(),e.getY(),lineTemp.x1,lineTemp.y1); //鼠标到直线起点的距离
                    int e_x2=getDist(e.getX(),e.getY(),lineTemp.x2,lineTemp.y2);//鼠标到直线终点的距离
                    if (e_x1+e_x2<x1_x2+2){
                        currentSelectLineTemp=lineTemp;//获捕捉到的直线
                        break;//捕捉到直线后，就退出循环
                    }else {
                        currentSelectLineTemp=null;//如果没有捕捉到，临时直线为空
                    }
                }
                for(int i=0;i<all.getCircleList().size();i++){ //遍历每一个圆
                    Circle ctemp=all.getCircleList().get(i);//获取每一根直线
                    int r = getDist(ctemp.x1,ctemp.y1,ctemp.x2,ctemp.y2);
                    int e_r = getDist(e.getX(),e.getY(),ctemp.x1,ctemp.y1);
                    if (e_r <= r+5 && e_r >= r-5)
                    {
                        currentSelectCircleTemp = ctemp;
                        break;
                    }else {
                        currentSelectCircleTemp = null;
                    }
                }
                if (currentSelectLineTemp!=null || currentSelectCircleTemp!=null){//如果有捕捉到直线
                    drawPanel.repaint(); //刷新绘图面板
                }

            }
        }
    }
    int getDist(int x1,int y1,int x2,int y2){
        int d= (int) Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
        return d;
    }
}
